/*
 ================================================================================
 Plik: f_and.c
 --------------------------------------------------------------------------------
 Autorzy: Piotr Zdunek, Mateusz Słowikowski, Krzysztof Wiąckowski
 Projekt:Model mikrokontrolera AVR
 Kompilator: avr-gcc-4.3.5
 Doc: doxygen 1.4.3
 --------------------------------------------------------------------------------
 Zawiera: Implementację funkcji AND
 --------------------------------------------------------------------------------
 Komentarze:
 ================================================================================
 */

/*! \file f_or.c
 * \brief Plik opisujący funkcję OR
 */

#include "types.h"
#include "mem_abs.h"

void F_OR(void) {
//	printf("Function OR.");

	/*!  void F_OR(void){}
		 *  \n \n
		 *  OR - operacja logiczna OR wykonywana na zawartościach rejestrów Rd i Rr, której
		 *  wynik jest zapisywany do rejestru Rd.
		 *
		 *  \ref pageor \n
		 */


#ifndef  DEBUG_MODE
	printf("Function OR.");
#endif
	//Pobranie rejestru flagowego z pamięci
	uint8_t FLAGS;
	FLAGS = GetFlagRegister();

	uint8_t Rd = (getMEMC(getPC()) & 0x00F0) >> 4; 						//identyfikacja numeru rejestru arg. 1
	uint8_t RdMSB = (((getMEMC(getPC()) & 0x0F00) >> 8) & 0b0001) << 4;
	Rd = RdMSB + Rd;

	uint8_t Rr = (getMEMC(getPC()) & 0x000F); 							//identyfikacja numeru rejestru arg. 2
	uint8_t RrMSB = (((getMEMC(getPC()) & 0x0F00) >> 8) & 0b0010) << 3;
	Rr = RrMSB + Rr;

	uint8_t Rd_val = getRegister(Rd) % MAX_DATA_VAL; 					//pobranie zawartosci rejestru arg 1
	uint8_t Rr_val = getRegister(Rr) % MAX_DATA_VAL; 					//pobranie zawartosci rejestru arg 2

	uint8_t R = (Rd_val | Rr_val); 										//obliczenie wyniku
																		//wypisanie zawartosci rejestrow -- czyste sprawdzenie czy wsjo ok
	//----------USTAWIENIA REJESTRU FLAG-----------

	ClearFlagRegisterBit(FLAG_V); // wyzerowanie flagi V

	if (((Rd & 0x80) >> 7) == 0 && ((R & 0x80) >> 7) == 1) // jeśli MSB Rd == 0 i MSB R == 1 to zmieniamy
		SetFlagRegisterBit(FLAG_N); // bo nastąpiła zmiana MSB
	else
		ClearFlagRegisterBit(FLAG_N);

	if (R == 0)
		SetFlagRegisterBit(FLAG_Z); //ustwienie flagi Z
	else
		ClearFlagRegisterBit(FLAG_Z);

	if ((GetFlagRegisterStatus(FLAG_N) ^ GetFlagRegisterStatus(FLAG_V)) == 1) { //ustwienie flagi S
		SetFlagRegisterBit(FLAG_S);
	} else
		ClearFlagRegisterBit(FLAG_S);

	setRegister(Rd, R); //Zapisanie wartosci rejestru do pamięci
	incPC(); //zwi�kszenie licznika rozkaz�w
}

/*! \page pageor Opis działania funkcji OR
 *
 *  OR - operacja logiczna OR wykonywana na zawartościach rejestrów Rd i Rr, której
 *  wynik jest zapisywany do rejestru Rd.
 *
 *	\dontinclude f_or.c
 *
 *	\section sec_or1 Operacje rejestrowe oraz arytmetyczno-logiczne
 *
 *	1. Pobranie adresów rejestrów Rd i Rr:
 *	\skipline getMEMC
 *	\until Rr = RrMSB + Rr
 *	2. Pobranie wartości z rejestru 1:
 *	\skipline getRegister(Rd)
 *	3. Pobranie wartości z rejestru 2:
 *	\skipline getRegister(Rr)
 *	4. Obliczenie wyniku operacji OR:
 *	\skipline Rd_val | Rr_val
 *
 *	\section sec_or2 Operacje na flagach
 *	1. Wyzerowanie flagi V
 *	\skipline FLAG_V
 *	2. Ustawienie flagi N
 *	\line if
 *	\until ClearFlagRegisterBit
 *	3. Ustawienie flagi Z
 *	\line if
 *	\until ClearFlagRegisterBit
 *	4. Ustawienie flagi S
 *	\line if
 *	\until ClearFlagRegisterBit
 *	5. Zapisanie nowej zawartości Rd
 *	\skipline setRegister
 *	6. Zwiększenie PC
 *	\skipline incPC
 *
 *	\section sec_or3 Kod źródłowy funkcji
 *
 *	\include f_or.c
 *
 */
